home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / dev / lang / pcq12src.lzh / Runtime / Readers / ReadInt.asm < prev    next >
Assembly Source File  |  1991-04-12  |  3KB  |  115 lines

  1.  
  2. *    ReadInt.asm (of PCQ Pascal runtime library)
  3. *    Copyright (c) 1989 Patrick Quaid
  4.  
  5. *    This routine reads an integer from a text file.
  6.  
  7.     INCLUDE    "/FileRec.i"
  8.  
  9.     SECTION    PCQ_Runtime,CODE
  10.  
  11.     XREF    _p%ReadOneChar
  12.     XREF    _p%GetThatChar
  13.     XREF    _p%IOResult
  14.  
  15. * Algorithm for ReadInt:
  16. *
  17. *    save variable address
  18. *    repeat
  19. *        Get the next character
  20. *        if we are at eof
  21. *        set IOResult
  22. *        fix stack
  23. *        return
  24. *        if current character is white space
  25. *        eat it
  26. *    until current character is not white space
  27. *    if the character is a linefeed
  28. *        set IOResult
  29. *        fix stack
  30. *        return
  31. *    if the character is '-' then
  32. *        IsMinus := True
  33. *        eat that character
  34. *        get the next one
  35. *    else
  36. *        IsMinus := False
  37. *    result := 0
  38. *    while the current character is a digit
  39. *        result := result * 10 + value of current character
  40. *        eat the character
  41. *        get the next character
  42. *    correct sign
  43. *    restore variable address
  44. *    return
  45.  
  46.  
  47. * Upon entry, a0 has the address of the variable to be updated.  Since
  48. * this routine will be used to read 32-bit integers as well as 16-bit
  49. * 'shorts', we simply pass a0 back to the caller.  On top of the stack
  50. * is the file record.
  51.  
  52.  
  53.     XDEF    _p%ReadInt
  54. _p%ReadInt
  55.  
  56.         move.l  a0,-(sp)        ; save file var address
  57.     tst.l    _p%IOResult    ; is IO OK?
  58.     bne    Abort
  59.     move.l    8(sp),a0    ; get the file record
  60. 1$    tst.b    EOF(a0)        ; are we at EOF?
  61.     bne    AbortEOF    ; if so, leave
  62.     jsr    _p%ReadOneChar    ; get the next character
  63.     tst.l    _p%IOResult    ; did it cause an error?
  64.     bne    Abort        ; if so, leave
  65.     cmp.b    #' ',d0        ; is the character white space?
  66.     bgt    AfterWhiteSpace ; if not, leave
  67.     jsr    _p%GetThatChar    ; advance the buffer pointer
  68.     bra    1$
  69. AbortEOF
  70.     move.l    #58,_p%IOResult    ; set EOF before first digit
  71. Abort
  72.     move.l    (sp)+,a0    ; get variable address
  73.     moveq.l    #0,d0        ; return 0
  74.     rts
  75.  
  76. AfterWhiteSpace
  77.     clr.w   -(sp)        ; IsMinus := False
  78.     cmp.b    #'-',d0        ; is the character a '-'
  79.     bne.s    3$        ; if not, skip this
  80.     jsr    _p%GetThatChar    ; eat the character
  81.     jsr    _p%ReadOneChar    ; and get the next one
  82.     move.w  #-1,(sp)    ; IsMinus := True
  83. 3$    cmp.b    #'0',d0        ; is first char a digit?
  84.     blt.s    NoNumber    ; if < 0 then is isn't
  85.     cmp.b    #'9',d0        ; keep checking
  86.     ble.s    DigitOK        ; is <= 9, we're OK
  87. NoNumber
  88.     move.l    #59,_p%IOResult    ; set No Digits for ReadInt
  89.     bra    Abort
  90. DigitOK
  91.     moveq    #0,d1        ; Result := 0
  92. 5$    cmp.b    #'0',d0        ;
  93.     blt    Leave        ; if < '0' leave now
  94.     cmp.b    #'9',d0
  95.     bgt    Leave        ; if > '9' leave
  96.     sub.b    #'0',d0        ; get digit value
  97.         mulu    #10,d1          ; d1 := d1 * 10
  98.     and.l    #15,d0        ; no funny business...
  99.     add.l    d0,d1        ; and add to running total
  100.     move.l    d1,-(sp)    ; save the running total
  101.     jsr    _p%GetThatChar    ; eat the current char
  102.     jsr    _p%ReadOneChar    ; get the next character
  103.     move.l    (sp)+,d1    ; get values back
  104.     tst.b    EOF(a0)        ; are we at eof?
  105.     beq    5$        ; if not, continue
  106. Leave
  107.     move.l    d1,d0        ; set up for return
  108.     move.w    (sp)+,d1    ; was it minus?
  109.     beq.s    6$        ; if not, skip this
  110.     neg.l    d0        ; d0 := -d0
  111. 6$    move.l    (sp)+,a0    ; retrieve variable address
  112.     rts
  113.  
  114.     END
  115.